﻿//_____________________________________________________________________________
//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//   Klasse: Tinare.EncrypterBase	Projekt: Tinare
//_____________________________________________________________________________
//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯
//   Beschreibung:
//        Die Encrypter Base bringt die Basis Klassen mit sich
//
//—————————————————————————————————————————————————————————————————————————————
//   © Minerva Group
//—————————————————————————————————————————————————————————————————————————————
//   Datum       Name            Tätigkeit
//   21.02.2009  broox           Erstellt
//
//
//—————————————————————————————————————————————————————————————————————————————
//_____________________________________________________________________________
//¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯¯

using System;
using System.Collections.Generic;

namespace Tinare
{
	public class EncrypterBase
	{
		protected Int32[] switchindex;
		protected Int32 unitsize = 5;
		protected Byte[] data;

		public EncrypterBase(Int32[] switchindex, Byte[] value)
		{
			this.switchindex = switchindex;
			this.data = value;
		}

		/// <summary>
		/// Verschlüsselt die Daten
		/// </summary>
		protected Byte[] Crypting(Byte[] value, Int32[] password)
		{
			List<Byte> cBytes = new List<byte>();

			for (Int32 units = 0; units < (value.Length); units = units + unitsize)
			{
				Byte[] unit = GetUnit(units, value, unitsize);

				if ((units + unitsize) != value.Length)
				{
					unit = MashBytes(unit, password);
				}
				
				cBytes.AddRange(unit);
			}

			return cBytes.ToArray();
		}
		/// <summary>
		/// Verschlüsselt eine Unit
		/// </summary>
		protected Byte[] MashBytes(Byte[] bytes, Int32[] switchindex)
		{
			for (Int32 i = 0; i < switchindex.Length; i = i + 2)
			{
				bytes = SwitchEntry(bytes, reroundUnit(switchindex[i], bytes.Length), reroundUnit(switchindex[i + 1], bytes.Length));
			}
			return bytes;
		}
		/// <summary>
		/// Gibt einen Integer zurück welcher sich im angegebenen Bereich befindet
		/// </summary>
		protected Int32 reroundUnit(Int32 i, Int32 size)
		{
			if (i >= size)
			{
				i = i - size;
			}
			else if (i < 0)
			{
				i = size + i;
			}

			return i;
		}
		/// <summary>
		/// Gibt teile eines Byte Arrays zurück
		/// </summary>
		protected Byte[] GetUnit(Int32 index, Byte[] value, Int32 length)
		{
			Byte[] temp = new Byte[length];
			Int32 c = 0;

			for (Int32 i = index; i < (index + length); i++)
			{
				temp[c] = value[i];
				c++;
			}

			return temp;
		}
		/// <summary>
		/// Fügt den Daten leere Bytes hinzu und ein Zeiger-Byte hinzu
		/// </summary>
		protected virtual Byte[] SetBytetoFive(Byte[] value)
		{
			List<Byte> bytes = new List<Byte>(value);
			Int32 counter = 0;

			while (((Convert.ToDecimal(bytes.Count) + 1) / unitsize).ToString().Contains("."))
			{
				bytes.Add(new Byte());
				counter++;
			}

			Byte lastByte = Convert.ToByte(counter);
			bytes.Add(lastByte);

			return bytes.ToArray();
		}
		/// <summary>
		/// Erstellt aus den Passwort Bytes ein Int Array
		/// </summary>
		protected static Int32[] GetSwitchValues(Byte[] value)
		{
			Int32[] switchvalues = new Int32[value.Length];
			for (Int32 i = 0; i < value.Length; i++)
			{
				switchvalues[i] = RecursivQuersumme(Convert.ToInt32(value[i]));
			}
			return switchvalues;
		}
		/// <summary>
		/// Berechnet die Quersumme bis die Zahl einstellig ist
		/// </summary>
		protected static Int32 RecursivQuersumme(Int32 number)
		{
			while (number.ToString().Length > 1)
			{
				number = Quersumme(number);
			}
			return number;
		}
		/// <summary>
		/// Berechnet die Quersumme einer Zahl
		/// </summary>
		protected static Int32 Quersumme(Int32 number)
		{
			Int32 ret = 0;

			foreach (Char chr in number.ToString())
			{
				ret += Convert.ToInt32(chr.ToString());
			}

			return ret;
		}
		/// <summary>
		/// Berechnet einen SHA1 Hash Digest
		/// </summary>
		protected static Byte[] SHA1Hash(String strString)
		{
			System.Security.Cryptography.SHA1CryptoServiceProvider SHA1 = new System.Security.Cryptography.SHA1CryptoServiceProvider();

			byte[] Data;

			Data = System.Text.Encoding.ASCII.GetBytes(strString);
			return SHA1.ComputeHash(Data);
		}
		/// <summary>
		/// Vertauscht die Bytes in einem Array
		/// </summary>
		protected Byte[] SwitchEntry(Byte[] bytes, Int32 place1, Int32 place2)
		{
			Byte temp = bytes[place1];
			bytes[place1] = bytes[place2];
			bytes[place2] = temp;
			return bytes;
		}
		/// <summary>
		/// Führt eine Cäsar Verschlüsselung durch
		/// </summary>
		protected virtual Byte[] Verschiebechiffre(Int32 move_index, Byte[] data)
		{
			for (Int32 i = 0; i < data.Length; i++)
			{
				Int32 rebyte = (Int32)data[i] + move_index;

				if (rebyte > 255)
				{
					rebyte -= 256;
				}
				else if (rebyte < 0)
				{
					rebyte += 256;
				}

				data[i] = Convert.ToByte(rebyte);
			}
			return data;
		}

		/// <summary>
		/// Das zu verschlüsselnde Byte
		/// </summary>
		public Byte[] Data
		{
			get { return data; }
			set { data = value; }
		}
		/// <summary>
		/// Die Unit Size (0 - 10)
		/// </summary>
		public Int32 UnitSize
		{
			get
			{
				return unitsize;
			}
			set
			{
				if (value < 1)
				{
					unitsize = 1;
				}
				else if (value > 10)
				{
					unitsize = 10;
				}
				else
				{
					unitsize = value;
				}
			}
		}
	}
}
